#!/usr/bin/python

import os,sys
import zlib
import re
import optparse

import gadget

def crc(fileName, excludeLine="", includeLine=""):
    MAX_LENGHT_ONCE = 10*1024*1024
    try:
        fd = open(fileName,"rb")
    except IOError:
        print "Unable to open the file in readmode:", filename
        return
    eachLine = fd.read(MAX_LENGHT_ONCE)
    if eachLine:
        prev = None
    while eachLine:
        if excludeLine and eachLine.startswith(excludeLine):
            continue   
        if not prev:
            prev = zlib.crc32(eachLine)
        else:
            prev = zlib.crc32(eachLine, prev)
        eachLine = fd.read(MAX_LENGHT_ONCE)
    fd.close()    
    return ('%08x'%(prev & 0xFFFFFFFF)).upper() #returns 8 digits crc


if __name__ == '__main__':
    p = optparse.OptionParser(description='md5 caluate/check/creat',
                          prog='md5.py',
                          version='%prog v0.1',
                          usage='%prog [options] File/Dir [File/Dir...]')
    p.add_option('--check', '-c', action="store_true", help='check a .sfv file', dest="check")
    p.add_option('--check2', '-f', action="store_true", help='check files with crc in filename', dest="check2")
    (options, args) = p.parse_args()
    
    if options.check == True:
        md5s = open(args[0],'r').readlines()
        dirpath = os.path.split(args[0])[0]
        for m in md5s:
            m = m.strip()
            if m.startswith(';'):
                continue
            crchash = m[m.rfind(' '):].strip().upper()
            filename = m[:m.rfind(' ')].strip()
            #print filename,crchash
            path = os.path.join(dirpath, filename)
            #print path
            if crchash.upper() == crc(path):
                print "Pass......", filename
            else:
                print "#Fail#......", filename            
        sys.exit()
    
    if options.check2 == True:
        reCRC = re.compile("([a-fA-F0-9]{8,8})")
        files = []
        for s in args:
            if os.path.isdir(s)==True:
                files.extend(gadget.walkDir(s))
            elif os.path.isfile(s)==True: 
                files.append(s)
            else:
                continue
        files.sort()
        for f in files:
            if os.path.splitext(f)[1] == '.ass':
                #do not hash ass file
                continue
            crcMatch = reCRC.search(f)
            if crcMatch is not None:
                crcstr = crcMatch.group(0)
                if crcstr.upper() == crc(f):
                    print "Pass...",f
                else:
                    print "#ERROR#...",f
        sys.exit()
        
    #generate sfv lines
    for a in args:
        if os.path.isfile(a) == True :
            print os.path.split(a)[1], crc(a)
        if os.path.isdir(a) == True :
            files = gadget.walkDir(a)
            folder = os.path.split(a)[1]
            for f in files:
                crchash = crc(f)
                print os.path.join(folder,f.replace(a,'')[1:]),crchash 
        
